/*
 Free Graphics Engine 
 0.0.1a
 dev.hddisseny
 100510
 Framework completo de la libreria SDL para usar en VC Express 8.
		   Creado por dev.hddisseny - dev.hddisseny@gmail.com 
**/

#include "FGElib.h"
/** Con este metodo se inicia el motor de la libreria. Y establece el titulo de la aplicacion<BR>
    Un ejemplo de <b>uso</b>:<BR><BR>

	<TABLE WIDTH="500" BGCOLOR="#ffffff" BORDERCOLOR="#000000"  BORDER= "0">
	<TR>
		<td>
			<i>
				FGE_Motion <b>GAME</b>;
				<BR><BR>
				<b>GAME</b>.Init( "Demo 0.0.1a" );
				<BR>
			</i>
		</td>
	</TR>
	</TABLE>
	\param __chTitle (char) - Titulo de al ventana 
*/
void FGE_Motion::Init( char* __chTitle )
{
	if ( SDL_Init ( SDL_INIT_EVERYTHING ) < 0 ) {
		exit(1);
    }
	SDL_WM_SetCaption ( __chTitle, NULL );
}

/** Con este metodo se crea una ventana nueva de las dimensiones especificadas, ademas de la profundidad del color.<BR>
    Un ejemplo de <b>uso</b>:<BR><BR>

	<TABLE WIDTH="500" BGCOLOR="#ffffff" BORDERCOLOR="#000000"  BORDER= "0">
	<TR>
		<td>
			<i>
				FGE_Motion <b>Demo</b>;
				<BR><BR>
				<b>Demo</b>.newWindow(200, 200, 16);
				<BR>
			</i>
		</td>
	</TR>
	</TABLE>
	
	\param __w (int) - Ancho de la ventana
	\param __h (int) - Alto de la ventana
	\param __bpp (int) - Profundida de color ( 8|16|24|32 )
*/
FGE_Screen * FGE_Motion::Window ( int __w, int __h, int __bpp )
{
	__pSurfaceBuffer = SDL_SetVideoMode( __w, __h, __bpp, SDL_DOUBLEBUF | SDL_SWSURFACE );
	return 0;
}

/** Con este metodo se devuelve la superficie para poder trabajar con ella<BR>
    Un ejemplo de <b>uso</b>:<BR><BR>

	<TABLE WIDTH="500" BGCOLOR="#ffffff" BORDERCOLOR="#000000"  BORDER= "0">
	<TR>
		<td>
			<i>
				FGE_Motion <b>Demo</b>;<BR>
				FGE_Screen <b>Pantalla</b>;
				<BR><BR>
				Pantalla = Demo.<b>Surface</b> ( );
				<BR>
			</i>
		</td>
	</TR>
	</TABLE>

	\return (FGE_Screen) - Devuelve la superficie del objeto
*/
FGE_Screen * FGE_Motion::Surface ( void )
{
	return __pSurfaceBuffer;
}

/** Con este metodo se refresca la superficie.<BR>
    Un ejemplo de <b>uso</b>:<BR><BR>

	<TABLE WIDTH="500" BGCOLOR="#ffffff" BORDERCOLOR="#000000"  BORDER= "0">
	<TR>
		<td>
			<i>
				FGE_Motion Demo;
				<BR><BR>
				Demo.<b>Refresh</b> (  );
				<BR>
			</i>
		</td>
	</TR>
	</TABLE>
*/
void FGE_Motion::Refresh ( void )
{
	if(SDL_MUSTLOCK( __pSurfaceBuffer )) {
       SDL_LockSurface( __pSurfaceBuffer );
    }

	if(SDL_MUSTLOCK( __pSurfaceBuffer )) {
       SDL_UnlockSurface( __pSurfaceBuffer );
    }
  
    SDL_Flip( __pSurfaceBuffer ); 
 }

/** Con este metodo se toman los eventos ocurridos con el teclado.<BR>
	El uso de las teclas es el siguiente. Si se aprieta una vez, se registrara solamente un movimiento. Sin embargo<BR>
	si se mantiene pulsada la tecla, este se hara continuo.<BR>
    Un ejemplo de <b>uso</b>:<BR><BR>

	<TABLE WIDTH="500" BGCOLOR="#ffffff" BORDERCOLOR="#000000"  BORDER= "0">
	<TR>
		<td>
			<i>
				FGE_Motion Demo;
				<BR><BR>
				switch ( Demo.Keyboard())<BR>
				{<BR>
					case FGE_ESC:<BR>
					printf("toma");<BR>
					break;<BR>
				}
				<BR>
			</i>
		</td>
	</TR>
	</TABLE>
	\return (int) - Devuelve el valor de la tecla pulsada, ver macros para facilitar su uso
*/
int FGE_Motion::Keyboard( void )
{
	while( SDL_PollEvent( &__pEventKeyboard) )
    {
		if( __pEventKeyboard.type == SDL_QUIT ) 
		{
			exit(0);
		}
		
		if( __pEventKeyboard.type == SDL_KEYDOWN ) 
        { 
			switch ( __pEventKeyboard.key.keysym.sym )
			{
				case SDLK_ESCAPE:
					 __iKeyPress = 1;
					break;
				case SDLK_UP:
					 __iKeyPress = 2;
					break;
				case SDLK_DOWN:
					 __iKeyPress = 3;
					break;
				case SDLK_LEFT:
					 __iKeyPress = 4;
					break;
				case SDLK_RIGHT:
					 __iKeyPress = 5;
					break;
				case SDLK_SPACE:
					 __iKeyPress = 6;
					break;
				case SDLK_RSHIFT:
					 __iKeyPress = 7;
					break;
				case SDLK_LSHIFT:
					 __iKeyPress = 8;
					break;
				case SDLK_RCTRL:
					 __iKeyPress = 9;
					break;
				case SDLK_LCTRL:
					 __iKeyPress = 10;
					break;
			}
			
		}

		if( __pEventKeyboard.type == SDL_KEYUP ) 
        { 
			__iKeyPress = 0;
		}
	}
	SDL_Delay(70);
	return __iKeyPress;
}

/** Con este metodo se toman los eventos ocurridos con el mouse.<BR>
    Un ejemplo de <b>uso</b>:<BR><BR>

	<TABLE WIDTH="500" BGCOLOR="#ffffff" BORDERCOLOR="#000000"  BORDER= "0">
	<TR>
		<td>
			<i>
				FGE_Motion Demo;
				<BR><BR>
				switch ( Demo.Mouse())<BR>
				{<BR>
					case 1:<BR>
					printf("Boton izquierdo del mouse pulsado");<BR>
					break;<BR>
				}
				<BR>
			</i>
		</td>
	</TR>
	</TABLE>
	\return (int) - Devuelve el valor del boton del mouse pulsado, ver macros para facilitar su uso
*/
int FGE_Motion::Mouse( void )
{
	switch (  SDL_GetMouseState( NULL, NULL ) )
	{
		case SDL_BUTTON(1):
			SDL_Delay(160);
			return 1;
			break;
		case SDL_BUTTON(2):
			SDL_Delay(160);
			return 2;
			break;
		case SDL_BUTTON(3):
			SDL_Delay(160);
			return 3;
			break;
	}
	return 0;
}

/** Con este metodo se carga una imagen en la superficie del objeto<BR>
    Un ejemplo de <b>uso</b>:<BR><BR>

	<TABLE WIDTH="500" BGCOLOR="#ffffff" BORDERCOLOR="#000000"  BORDER= "0">
	<TR>
		<td>
			<i>
				FGE_Media <b>Img</b>;
				<BR><BR>
				<b>Img</b>.LoadImg( "1.bmp" );
				<BR>
				<BR>
				<b>O tambien :</b><BR>
				<BR>
				if ( ( <b>Img</b>.LoadImg ( "1.bmp" ) ) != 0 ) { printf("Erro, fichero no valido"); }
			</i>
		</td>
	</TR>
	</TABLE>
	\param __chPath (char) - Direccion de la imagen 
	\return Retorna 0 si todo a salido bien, sino retorna 1.
*/
int FGE_Media::LoadImg( char *__chPath )
{
	if ( ( __pImageBuffer = IMG_Load ( __chPath )) != NULL ) { return 0; } else { return 1; }
}

/** Con este metodo se dibuja una imagen en la superficie deseada. El punto de anclaje esta en el centro de la superficie<BR>
    Un ejemplo de <b>uso</b>:<BR><BR>

	<TABLE WIDTH="500" BGCOLOR="#ffffff" BORDERCOLOR="#000000"  BORDER= "0">
	<TR>
		<td>
			<i>
				FGE_Motion Demo;<BR>
				FGE_Media <b>Img</b>;
				<BR><BR>
				<b>Img</b>.LoadImg( "1.bmp" );
				<BR>
				Img.DrawImage ( 100, 100, Demo.Surface() );
				<BR>
			</i>
		</td>
	</TR>
	</TABLE>
	\param __pX (int) - Posicion X 
	\param __pY (int) - Posicion Y
	\param __sSurfaceDest (FGE_Screen) - Superficie de destino al pintar, por defecto es la creada desde FGE_Motion. 
*/
void FGE_Media::DrawImage(int __pX, int __pY, FGE_Screen *__sSurfaceDest)
{
	__posX = __pX;
	__posY = __pY;

	__bImageBox.x = __posX -__pImageBuffer->w/2;
	__bImageBox.y = __posY -__pImageBuffer->h/2;
	
	 SDL_BlitSurface ( __pImageBuffer , NULL, __sSurfaceDest, &__bImageBox ); 
}

/** Con este metodo se establece el color de transparencia de la imagen.Por las especificaciones de SDL<BR>
 <b>solo funciona con imagenes BMP</b>. Las imagenes png soportan transparencia por su propio canal alpha.<BR>
    Un ejemplo de <b>uso</b>:<BR><BR>

	<TABLE WIDTH="500" BGCOLOR="#ffffff" BORDERCOLOR="#000000"  BORDER= "0">
	<TR>
		<td>
			<i>
				FGE_Motion Demo;<BR>
				FGE_Media <b>Img</b>;
				<BR><BR>
				Img.LoadImg( "1.bmp" );
				Img.<b>SetColorKey</b> ( 255, 0 , 255 );
				<BR>
				Img.DrawImage ( 100, 100, Demo.Surface() );
				<BR>
			</i>
		</td>
	</TR>
	</TABLE>
	\param __r (int) - Componente Rojo  (0-255) 
	\param __g (int) - Componente Verde (0-255)
	\param __b (int) - Componente Azul  (0-255) 
*/
void FGE_Media::SetColorKey( int __r, int __g, int __b ) 
{
	SDL_SetColorKey( __pImageBuffer, SDL_SRCCOLORKEY | SDL_RLEACCEL, SDL_MapRGB(__pImageBuffer->format, __r, __g ,__b));
}

/** Devuelve el ancho de una superficie<BR>
    Un ejemplo de <b>uso</b>:<BR><BR>

	<TABLE WIDTH="500" BGCOLOR="#ffffff" BORDERCOLOR="#000000"  BORDER= "0">
	<TR>
		<td>
			<i>
				FGE_Media <b>Img</b>;
				<BR><BR>
				Img.LoadImg( "1.bmp" );
				<BR>
				<BR>
				w = Img.<b>ImgWidth</b>();
			</i>
		</td>
	</TR>
	</TABLE>
	\return Retorna el ancho de una superficie.
*/
int FGE_Media::ImgWidth( void )
{
	return __pImageBuffer->w;
}

/** Devuelve el alto de una superficie<BR>
    Un ejemplo de <b>uso</b>:<BR><BR>

	<TABLE WIDTH="500" BGCOLOR="#ffffff" BORDERCOLOR="#000000"  BORDER= "0">
	<TR>
		<td>
			<i>
				FGE_Media <b>Img</b>;
				<BR><BR>
				Img.LoadImg( "1.bmp" );
				<BR>
				<BR>
				h = Img.<b>ImgHeight</b>();
			</i>
		</td>
	</TR>
	</TABLE>
	\return Retorna el alto de una superficie.
*/
int FGE_Media::ImgHeight( void )
{
	return __pImageBuffer->h;
}

/** Devuelve la posicion X de una superficie<BR>
    Un ejemplo de <b>uso</b>:<BR><BR>

	<TABLE WIDTH="500" BGCOLOR="#ffffff" BORDERCOLOR="#000000"  BORDER= "0">
	<TR>
		<td>
			<i>
				FGE_Media <b>Img</b>;
				<BR><BR>
				Img.LoadImg( "1.bmp" );
				<BR>
				<BR>
				h = Img.<b>ImgX</b>();
			</i>
		</td>
	</TR>
	</TABLE>
	\return Retorna la posicion X de una superficie.
*/
int FGE_Media::ImgX( void )
{
	return __posX;
}

/** Devuelve la posicion Y de una superficie<BR>
    Un ejemplo de <b>uso</b>:<BR><BR>

	<TABLE WIDTH="500" BGCOLOR="#ffffff" BORDERCOLOR="#000000"  BORDER= "0">
	<TR>
		<td>
			<i>
				FGE_Media <b>Img</b>;
				<BR><BR>
				Img.LoadImg( "1.bmp" );
				<BR>
				<BR>
				h = Img.<b>ImgY</b>();
			</i>
		</td>
	</TR>
	</TABLE>
	\return Retorna la posicion Y de una superficie.
*/
int FGE_Media::ImgY( void )
{
	return __posY;
}

/** Devuelve la superficie<BR>
    Un ejemplo de <b>uso</b>:<BR><BR>

	<TABLE WIDTH="500" BGCOLOR="#ffffff" BORDERCOLOR="#000000"  BORDER= "0">
	<TR>
		<td>
			<i>
				FGE_Media <b>Img</b>;
				<BR><BR>
				Img.Surface( );
				<BR>
			</i>
		</td>
	</TR>
	</TABLE>
	\return Retorna la superficie.
*/
FGE_Screen * FGE_Media::Surface( void )
{
	return __pImageBuffer;
}